#include <REGX52.H>
#include "delay.h"

sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_E = P2^7;

#define LCD1602_DATAPORT P0

/** @bref LCD1602写入命令
  * @param 写入的命令
  * @retval 无
  */
void LCD1602_writeCommand(unsigned char command)
{
	LCD1602_RS = 0;
	LCD1602_RW = 0;
	LCD1602_DATAPORT = command;
	LCD1602_E = 1;
	delay(1);
	LCD1602_E = 0;
	delay(1);
}

/** @bref LCD1602写入数据
  * @param 写入的数据
  * @retval 无
  */
void LCD1602_writeData(unsigned char Data)
{
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DATAPORT = Data;
	LCD1602_E = 1;
	delay(1);
	LCD1602_E = 0;
	delay(1);
}

/** @bref LCD1602初始化
  * @param 无
  * @retval 无
  */
void LCD1602_init()
{
	LCD1602_writeCommand(0x38);
	LCD1602_writeCommand(0x0C);
	LCD1602_writeCommand(0x06);
	LCD1602_writeCommand(0x01);
}

/** @bref LCD1602设置光标位置
	* @param row 行号
	* @param column 列号
  * @retval 无
  */
void LCD1602_setCursor(unsigned char row, unsigned char column)
{
	// 若要显示在第一行
	if(row == 1)
	{
		LCD1602_writeCommand(0x80 | (column - 1));
	}
	// 若要显示在第二行
	else
	{
		LCD1602_writeCommand((0x80 | (column - 1)) + 0x40);
	}
}

/** @bref LCD1602显示一个字符
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的字符
  * @retval 无
  */
void LCD1602_showChar(unsigned char row, unsigned char column, unsigned char Data)
{
	LCD1602_setCursor(row, column);
	LCD1602_writeData(Data);
}

/** @bref LCD1602显示一个字符串
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的字符串
  * @retval 无
  */
void LCD1602_showString(unsigned char row, unsigned char column, unsigned char* Data)
{
	unsigned char i = 0;
	LCD1602_setCursor(row, column);
	for(i = 0; Data[i] != '\0'; i++)
	{
		LCD1602_writeData(Data[i]);
	}
}

/** @bref 获得x的y次方
  * @param x 底数
  * @param y 幂
  * @retval x的y次方
  */
int LCD1602_pow(int x, int y)
{
	int result = 1;
	unsigned char i = 0;
	for(i = 0; i < y; i++)
	{
		result *= x;
	}
	
	return result;
}

/** @bref LCD1602显示一个数值
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的数值
	* @param length 显示的长度
  * @retval 无
  */
void LCD1602_showNum(unsigned char row, unsigned char column, unsigned int Data, unsigned char length)
{
	unsigned char i = 0;
	LCD1602_setCursor(row, column);
	for(i = length; i > 0; i--)
	{
		LCD1602_writeData('0' + Data/LCD1602_pow(10, (i - 1))%10);
	}
}

/** @bref LCD1602显示一个数值（有符号）
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的数值
	* @param length 显示的长度
  * @retval 无
  */
void LCD1602_showSignedNum(unsigned char row, unsigned char column, int Data, unsigned char length)
{
	unsigned char i = 0;
	unsigned int temp;
	
	LCD1602_setCursor(row, column);
	if(Data >= 0)
	{
		LCD1602_writeData('+');
		temp = Data;
	}
	else
	{
		LCD1602_writeData('-');
		temp = -Data;
	}
	for(i = length; i > 0; i--)
	{
		LCD1602_writeData('0' + temp/LCD1602_pow(10, (i - 1))%10);
	}
}

/** @bref LCD1602显示一个十六进制数
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的十六进制数
	* @param length 显示的长度
  * @retval 无
  */
void LCD1602_showHexNum(unsigned char row, unsigned char column, unsigned int Data, unsigned char length)
{
	unsigned char i = 0;
	unsigned char singleNumber;
	LCD1602_setCursor(row, column);
	for(i = length; i > 0; i--)
	{
		singleNumber = Data/LCD1602_pow(16, (i - 1))%16;
		if(singleNumber >= 10)
		{
			LCD1602_writeData('A' + singleNumber - 10);
		}
		else
		{
			LCD1602_writeData('0' + singleNumber);
		}
	}
}

/** @bref LCD1602显示一个二进制数
	* @param row 行号
	* @param column 列号
	* @param Data 要显示的十六进制数
	* @param length 显示的长度
  * @retval 无
  */
void LCD1602_showBinNum(unsigned char row, unsigned char column, unsigned int Data, unsigned char length)
{
	unsigned char i = 0;
	LCD1602_setCursor(row, column);
	for(i = length; i > 0; i--)
	{
		LCD1602_writeData('0' + Data/LCD1602_pow(2, (i - 1))%2);
	}	
}